
package com.xbongbong.pro.domain.entity;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.I18nStringConstant;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import org.springframework.context.i18n.LocaleContextHolder;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

/**
* @author autoGen
* @time 2019-01-07 11:13:40
*/
@Setter
@Getter
@ToString
public class ChartEntity {
	private static final long serialVersionUID = 2879846296086737741L;

	public ChartEntity (){
		del = 0;
		updateTime = (long)DateUtil.getInt();

	}
	/**
	* 主键id
	*/
	private Long id;
	/**
	* 公司id
	*/
	private String corpid;
	/**
	* 分类id数组
	*/
	private JSONArray category;
	/**
	* 指标类型：1系统指标,2自定义指标
	*/
	@NotNull(message = "指标类型不能为空")
	@Range(min=1,max=2,message = "指标类型传值异常")
	protected Integer statisticsType;
	/**
	* 系统指标枚举code，用于直接定位系统指标，处理特殊逻辑更方便
	*/
	private String systemCode;
	/**
	 * 前端生成的唯一标识（保存报表是批量保存，需要把新增后生成的主键id与该值对应）
	 */
	private String uuid;
	/**
	* 是否开启：0关闭,1开启
	*/
	@NotNull(message = "是否开启不能为空")
	@Range(min=0,max=1,message = "是否开启传值异常")
	protected Integer enable;
	/**
	* 报表类型，用枚举维护
	*/
	@NotNull(message = "报表类型不能为空")
	protected Integer chartType;
	/**
	* 是否发布到首页：0否,1是
	*/
	@NotNull(message = "是否发布到首页不能为空")
	@Range(min=0,max=1,message = "是否发布到首页传值异常")
	protected Integer publish;
	/**
	* 报表名称
	*/
	@Length(min = 1, max = 100)
	private String name;
	/**
	 * 报表英文名称
	 */
	@Length(min = 1, max = 100)
	private String nameEn;
	/**
	* 报表名称
	*/
	private String oldName;
	/**
	* 指标简介
	*/
	@Length(max = 500)
	private String memo;
	/**
	* 指标/图表图标
	*/
	private String icon;
	/**
	* 颜色，16进制色，如 #FF0000
	*/
	private String color;
	/**
	* 1单表，0多表
	*/
	private Integer single;
	/**
	 * 1单表，0多表
	 */
	private Integer muti;
	/**
	* 业务类型,主要用于对系统指标的业务分类做标记，格式为：[1,2]
	*/
	private String refTypes;
	/**
	* 统计方式
	* @see com.xbongbong.paas.enums.AggTypeEnum
	*/
	private Integer statisticsWay;
	/**
	* 单位（系统指标的单位可默认，如合同金额为“元”）
	*/
	private String unit;
	/**
	* 排序字段
	*/
	private Integer sort;
	/**
	* 创建者id
	*/
	private String creatorId;
	/**
	* 创建时间
	*/
	private Long addTime;
	/**
	* 更新时间
	*/
	private Long updateTime;
	/**
	 * 图表设置与数据集设置的对比时间
	 */
	private Long dataSetCompareTime;
	/**
	* 删除标记
	*/
	private Integer del;
	/**
	 * 报表权限+数据权限dataPermissionAttr
	 * {"export": 0, "visible": 0, "exportRule": {"dep": [], "role": [], "type": 2, "user": []}, "visibleScopeRule": {"dep": [], "role": [], "type": 2, "user": []}, "visibleScopeEnable": 0, "exportAdvanceEnable": 0
	 * , "dataPermissionAttr" : {"attr": "creatorId", "originalAttr" : "creatorId_1"}}
	 */
	private JSONObject permissions;
	/**
	 * 用于存放报表的共用配置：操作权限，表头冻结，格式：[{}]
	 */
	private JSONObject  explains;
	/**
	 * 筛选条件 格式：[{}]
	 */
	private JSONArray filter;
	/**
	 * 分类：X轴上的分组，单选，格式为{"attr": "name", "sumWay": 1, "attrType":1}
	 */
	private JSONArray chartClassify;
	/**
	 * 系列：在分类的基础上，对分类字段的值再次进行分组，可多选.格式为：[{"attr": "name", "sumWay": 1, "attrType":1}]
	 */
	private JSONArray  chartSeries;
	/**
	 * 值：分类与系列组成分组，指标为需要统计的数据，值与Y轴对应；只有数字字段可以作为指标，另外系统自带的计数也可以；可多选，格式为：[{"attr": "name", "sumWay": 1, "attrType":1}]
	 */
	private JSONArray  chartValue;
	/**
	 * 联动：关联其他报表id数组，即当前表的主键，格式为：[1,2]。数据查询表不能主动联动
	 */
	private JSONArray linkIds;
	/**
	 * 单个图表的查询条件
	 */
	private JSONArray search;
	/**
	 * 主表数据来源，只能有一个，代表主驱动表 格式为：{"appId":1,"menuId":2,"linkAttr":"text_1"}
	 */
	private JSONObject  driverSources;
	/**
	 * 从表数据源，最多两个 [{"appId":1,"menuId":2,"linkAttr":"text_1"}, {"appId":2,"menuId":1,"linkAttr":"text_1"}]
	 */
	private JSONArray slaveSources;
	/**
	 * 展示字段[{"name":"分类id","attr":"categoryName"}]
	 */
	private JSONArray displayAttr;
	/**
	 * 汇总字段[{"name":"","attr":""}]
	 */
	private JSONArray summaryAttr;
	/**
	 * 计算字段[{"name":"","attr":""}]
	 */
	private JSONArray computedAttr;
	/**
	 * 计算字段涉及到的数字字段[{"name":"","attr":""}]
	 */
	private JSONArray computedNumAttr;

	/*
	 * 汇总方式 -1:不汇总 0:小计 1：总计
	 */
	private Integer sum;
	/**
	 * 分组字段[{"name":"","attr":""}]
	 *
	 */
	private JSONArray groupAttr;

	/**
	 * 行分组字段[{"name":"","attr":""}]
	 */
	private JSONArray rowGroupAttr;

	/**
	 * 列分组字段[{"name":"","attr":""}]
	 */
	private JSONArray colGroupAttr;
	/**
	 * 统计的字段，{"name":"字段名","attr":"attr1"}。统计的数字型业务字段，如果是获取指标值(且不是求总数)的，则该条件必选
	 */
	private JSONObject sourceAttr;
	/**
	 * 归属人字段，{"name":"","attr":"userId"}。按照哪一个归属字段统计（如创建人、签订人等）
	 */
	private JSONObject belongAttr;
	/**
	 * 时间字段，{"name":"","attr":""}。按照哪一个时间范围字段进行统计（如创建时间、自定义的时间类型字段）
	 */
	private JSONObject timeAttr;
	/**
	 * 可展示的图表类型列表--主要兼容首页系统图表展示
	 * [1,2]
	 */
	@NotNull(message = "报表可展示的类型不能为空")
	protected JSONArray showTypes;

	/**
	 * 扩展字段，前端传入的分类id，在设置时会转为json数组格式
	 */
	private Long categoryId;

	/**
	 * 穿透展示字段[{"name":"","attr":""}]
	 */
	private JSONArray penetrateAttr;
	/**
	 * formId:{originalAttr:attr}
	 *{"5093": {"text_52": "text_2"}, "5098": {"num_1": "num_1", "text_1": "text_1", "serialNo": "serialNo"}}
	 */
	private JSONObject formIdAttr;
	/**
	 * 已选择的字段 格式  key 为 originalAttr+"-"+formId
	 *                                value 为explain 和新的attr
	 * {"num_1-10375":{"attr":"num_1","attrName":"合同金额","attrType":"num","fieldType":2,"formId":10375,"items":[],"originalAttr":"num_1"}}
	 */
	private JSONObject selectedAttr;
	/**
	 * 指标图的展示模式  1 小 2 中 3 大
	 **/
	private Integer displayModel;
	/**
	 * 单个图表的样式
	 **/
	private JSONObject itemStyleOption;

	/**
	 * [{property: "dept", editable: 1, id: 5, name: "研发部"},
	 * {property: "role", editable: 1, id: "2", name: "角色2"},
	 * {property: "user", editable: 1, id: "1", name: "张杰"}]
	 * Pk榜范围设置参与的人员
	 */
	private JSONArray joinRule;
	/**
	 * [{property: "dept", editable: 1, id: 5, name: "研发部"},
	 * {property: "role", editable: 1, id: "2", name: "角色2"},
	 * {property: "user", editable: 1, id: "1", name: "张杰"}]
	 * Pk榜范围设置不参与的人员
	 */
	private JSONArray removeRule;
	/**
	 * [{property: "dept", editable: 1, id: 5, name: "研发部"},
	 * {property: "role", editable: 1, id: "2", name: "角色2"},
	 * {property: "user", editable: 1, id: "1", name: "张杰"}]
	 * Pk榜可见权限范围
	 */
	private JSONArray scopeRule;

	/**
	 * Pk榜可见范围设置，可见数据权限类型，0，数据权限，1，全部数据   2，全公司top3 + 数据权限
	 */
	private Integer powerType;
    /**
     * 机会的输单/取消，默认都是开启的，先不需要刷
     * [{"config":"funnelOpportunityLostOrderButton","configValue":"1"},{"config":"funnelOpportunityCancelButton","configValue":"1"}]
     * 客户的流失，默认都是开启的，先不需要刷
     * [{"config":"funnelCustomerRunOffButton","configValue":"1"}]
     * 按钮开关配置
     */
	private JSONArray buttonAttr;
	/**
	 * 双轴图信息
	 */
	private JSONObject biaxial;
	/**
	 * 双轴图右侧统计值
	 */
	private JSONArray chartValueSecond;
	/**
	 * 指标图副指标
	 */
	private JSONArray secondTargetAttr;
	/**
	 * 数值格式
	 */
	private Integer numFormat;
	/**
	 * 地图信息
	 */
	private JSONObject map;
	/**
	 * 前端地图需要信息
	 */
	private String mapDistrict;
	/**
	 * 自定义漏斗信息
	 */
	private JSONObject funnel;
	/**
	 * 图表钻取层级信息
	 * 内部JSONObject对应的pojo实体为：@link ChartDrillInfoPojo
	 *      即该drill可以转为List<ChartDrillInfoPojo>：List<ChartDrillInfoPojo> drillList = JsonHelperUtil.parseArray(JSON.toJSONString(drill), ChartDrillInfoPojo.class);
	 *      或者也可以转为List<FieldAttrPojo>
	 */
	private JSONArray drill;

    /**
     * 主要是统计图配合前端使用：图上卷、下钻时，遇到特殊字段（部门、产品分类）时，由于不应该找上一个、下一个钻取字段，而应该还是本身。前端无法判断，需要后端处理特殊字段后根据情况（没有上一级、下一级时才换新的字段）确定是否改变 drillIndex
     * 分类、系列字段（上卷下钻过的话，用钻取目标字段匹配）与层级字段匹配到时，该字段在层级内的索引
     */
	private Integer drillIndex;

	/**
	 * 保留图表原始的第一个行分组字段（钻取时行分组字段可能会被替换，拼接统计表小计sql时使用）
	 */
	private JSONObject originalRowField;

	/**
	 * 图表联动设置
	 */
	private JSONArray chartLinkage;

	/**
	 * 设置分类信息，内部转为json数组形式
	 * @param categoryId 前端传入的分类id
	 * @author zcp
	 * @date 2019/3/19 10:28
	 * @since v1.0
	 * @version v1.0
	 */
	public void setCategoryId2Category(Long categoryId) {
		if (categoryId == null) {
		    return;
		}
		this.category = JSONArray.parseArray("[" + categoryId + "]");
	}

	/**
	 * 获取分类id
	 * @return java.lang.Long
	 * @author zcp
	 * @date 2019/5/21 10:36
	 * @since v1.0
	 * @version v1.0
	 */
	public Long getCategoryId() {
		Long nullCategoryId = 0L;
		if (this.category == null) {
			return nullCategoryId;
		}
		List<Long> cidList = this.category.toJavaList(Long.class);
		if (cidList == null || cidList.size() == 0) {
			return nullCategoryId;
		}
		return cidList.get(0);
	}

	/**
	 * 获取二级分类id
	 * @param
	 * @return java.lang.Long
	 * @author xinpeng.jiang
	 * @date 2022/3/25 10:26
	 * @version 1.0
	 */
	public Long getCategoryId4Second() {
		Long nullCategoryId = 0L;
		if (this.category == null) {
			return nullCategoryId;
		}
		List<Long> cidList = this.category.toJavaList(Long.class);
		if (cidList == null || cidList.size() <= 1) {
			return nullCategoryId;
		}
		return cidList.get(1);
	}

	public void setCategory(JSONArray category) {
		this.category = category;
	}

	public String getName() {
		Locale locale = LocaleContextHolder.getLocale();
		if (Objects.equals(locale.getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)&& StringUtil.isNotEmpty(nameEn)) {
			return nameEn;
		}
		return RegexUtil.getVariableName(name);
	}

	public String getNameEn() {
		Locale locale = LocaleContextHolder.getLocale();
		if (Objects.equals(locale.getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)) {
			return RegexUtil.getVariableName(name);
		}
		return nameEn;
	}

	public String getOldName() {
		return RegexUtil.getVariableName(oldName);
	}

	public String getMemo() {
		return RegexUtil.getVariableName(memo);
	}

	public String getUnit() {
		Locale locale = LocaleContextHolder.getLocale();
		// 后期可以把限制去掉,因为客户提的只要首页去掉,图表中心就原样吧
		if (Objects.equals(locale.getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)) {
			return null;
		}
		return unit;
	}

	public String getOriginalUnit() {
		return unit;
	}

	/**
	 * 设置pk榜特有参数默认值
	 * @author xinpeng.jiang
	 * @date 2022/3/17 15:41
	 * @version 1.0
	 */
	public void setPkParams() {
		this.joinRule = new JSONArray();
		this.removeRule = new JSONArray();
		this.scopeRule = new JSONArray();
		this.powerType = 0;
	}
}

